package ch.zbw.sysventory.server.repository.impl;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.springframework.stereotype.Repository;

import ch.zbw.sysventory.server.model.ComputerScan;
import ch.zbw.sysventory.server.model.ComputerScanResult;
import ch.zbw.sysventory.server.repository.ComputerScanResultRepositoryCustom;

@Repository
public class ComputerScanResultRepositoryCustomImpl implements ComputerScanResultRepositoryCustom {

	@PersistenceContext
	private EntityManager entityManager;

	public void setEntityManager(EntityManager entityManager) {
		this.entityManager = entityManager;
	}

	public EntityManager getEntityManager() {
		return entityManager;
	}

	@Override
	public List<ComputerScanResult> getComputerScanSearchResults(ComputerScan latestScan, String searchCombination, String computerName, String ipAddress, String type,
			String cpuType, String operatingSystem) {
		CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<ComputerScanResult> criteriaQuery = criteriaBuilder.createQuery(ComputerScanResult.class);
		Root<ComputerScanResult> from = criteriaQuery.from(ComputerScanResult.class);
		CriteriaQuery<ComputerScanResult> select = criteriaQuery.select(from);

		Predicate computerScanPredicate = criteriaBuilder.equal(from.get("computerScan"), latestScan);
		Predicate computerNamePredicate = criteriaBuilder.like(criteriaBuilder.lower(from.<String> get("computerName")), "%" + computerName.toLowerCase() + "%");
		Predicate computerIpAddressPredicate = criteriaBuilder.like(criteriaBuilder.lower(from.<String> get("scanIpAddress")), "%" + ipAddress.toLowerCase() + "%");
		Predicate computerCpuPredicate = criteriaBuilder.like(criteriaBuilder.lower(from.<String> get("cpu")), "%" + cpuType.toLowerCase() + "%");
		Predicate osPredicate = criteriaBuilder.like(criteriaBuilder.lower(from.<String> get("operatingSystem")), "%" + operatingSystem.toLowerCase() + "%");

		if ("or".equals(searchCombination)) {
			select.where(criteriaBuilder.and(computerScanPredicate, criteriaBuilder.or(computerNamePredicate, computerIpAddressPredicate, computerCpuPredicate, osPredicate)));
		} else {
			select.where(criteriaBuilder.and(computerScanPredicate, criteriaBuilder.and(computerNamePredicate, computerIpAddressPredicate, computerCpuPredicate, osPredicate)));
		}

		TypedQuery<ComputerScanResult> typedQuery = entityManager.createQuery(select);
		List<ComputerScanResult> resultList = typedQuery.getResultList();
		return resultList;
	}

}
